/*导入 react 框架包 这个包里面有提供
* 1. 提供了 虚拟dom 的 api （React.createElement()）
* 2. 提供了 组件的父类 React.Component
* ...
* */
import React from 'react';


/*
* ReactDOM 库可以把我们react里面的虚拟dom（js对象）转换为真实的dom（document.createElement document.appendChild）插入页面
* */
import ReactDOM from 'react-dom';

/*
* css文件 项目的初始化操作
* 1. reset.css
* 2. common.css
*
* */
import './index.css';

/*
* App 称之为 项目的 主组件，到时候我们基于 react 做开发，都是使用 react 的组件化思想进行开发的，到时候我们会把各种组件统一规整到 App.js 这个组件里面进行管理。主要是为了统一管理方便。
* */
import App from './App';
// import App from './App.js';

/*性能检查*/
import reportWebVitals from './reportWebVitals';


/*
* ReactDOM.render 可以把我们的 react的虚拟dom转换为真实的dom插入到页面的api
*
* 参数1：待插入到页面的虚拟dom ，组件
*   React.StrictMode 是 react内置的一个组件，开始 react的严格模式
*   'use strict'
*
*    <App /> 就是我们用户自己开发的组件  import App from './App';
*
*
* 参数2：插入的容器位置  document.getElementById('root')
*   public/index.html-->id=root dom区域
*
*
* */


/*学习 jsx 语法：  如果不使用 jsx语法，而是使用 内置的api去创建虚拟 dom 是非常麻烦的。*/

/*不是 jsx 去描述一个虚拟dom
* <div id="box">我是一个div的盒子</div>
*
* 嵌套：
* <div id="box">我是一个div的盒子 <p>我是一个p段落</p></div>
* */
let virtualDomp = React.createElement('p', null, '我是一个p段落');
let virtualDom1 = React.createElement('div', {id: 'box'}, '我是一个div的盒子', virtualDomp);

console.log(virtualDom1);

// 1.jsx(便捷)---webpack--babel(js语法进行转换)---> React.createElement(虚拟dom)--->ReactDOM.render(转换为真实的 dom)---->插入到页面
// jsx语法实现虚拟dom节点，比上面的语法要简洁很多。

// https://www.babeljs.cn/repl#?browsers=&build=&builtIns=false&corejs=3.6&spec=false&loose=false&code_lz=DwEwlgbgBGILwCIBGB7AHggfIRCND0ZoADlAqOXAkBC3QJbdAFbSmAAccDDbBW60F4Q4Aens5MyA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=es2015%2Ces2016%2Ces2017%2Creact%2Cstage-0%2Cstage-1%2Ces2015-loose&prettier=false&targets=&version=7.17.8&externalPlugins=&assumptions=%7B%7D

// let jsxElement = <div id="box">我是一个div的盒子 <p>我是一个p段落</p></div>;
//{ } 插值表达式

/*
* 1. 注意事项：必须有且仅有一个根节点
*   1.1 可以使用 空标签来替代无意义的根节点。
*   1.2 可以使用层级和缩进
*   1.3 为了使得jsx语法是一个整体，我们一般在最外层加上一个括号。
*
* 2. 注意事项：所有的标签必须闭合（无论是单还是双标签）
*
* 3. 注意事项：标签的 class(className="box") 和 for 这些属性，必须使用另外一个别名替代。
*
* */

/*
* jsx语法
* 1. 直接在 javascript语境下写html代码即可
* 2. jsx里面如果要插入变量，则需要使用插值表达式
*   { }  插值表达式，只有一个大括号，我们把插入的变量放置到 插值表达式里面即可。到时候会将内容渲染到页面上面。
*       2.1 插值表达式的前后，一般我们习惯加上空格 为了便于阅读
*
* */

let richContent = '<h1>我是由富文本编辑器得到的内容</h1>';

let title = '我是标题，今天学习了 react 的jsx语法'; // string 类型
let number1 = 142;
let number2 = 102;

// 复合数据类型（1. 单个的值（数组 元素；对象属性值） 2. 遍历）
let arr = [12, 23, 34];
let obj = {id: 12, username: 'andy', email: 'gogery@163.com'};

/*对象数组 后台列表接口，返回的一般是这种结构的数据*/
let users = [
    {id: 12, username: 'andy', email: 'gogery@163.com'},
    {id: 13, username: 'mark', email: 'mark@163.com'},
    {id: 14, username: 'alx', email: 'alx@sina.com'},
];

function add(a, b) {
    return a + b;
}

/*1. jsx里面的条件判断 三目 */
/*2. jsx里面还可以做四则运算 + - * / % +字符串拼接*/
/*3. ECMAScript里面的函数 Math.random parseInt 和用户自定义函数....*/
let jsxElement = (
    <>
        <h1>{title}</h1>
        <div>
            {richContent}
        </div>
        {/*dangerouslySetInnerHTML 可以使用的我们的插值表达式不会对内容进行转义*/}
        <div dangerouslySetInnerHTML={ {__html: richContent} }></div>
        <h2>jsx实现四则运算</h2>
        <hr/>
        <p>{number1 + number2}</p>
        <p>{number1 - number2}</p>
        <p>{number1 * number2}</p>
        <p>{number1 / number2}</p>
        <p>{number1 % number2}</p>
        <hr/>
        <p>number1 > number2： {number1 > number2 ? '真的' : '假的'}</p>

        {title + '，我是拼接在title后面的字符串'}

        <hr/>
        <h2>jsx调用ECMAScript相关函数</h2>
        <p>{Math.random()}</p>
        <p>{parseInt(12.234)}</p>
        <p>{add(12, 23)}</p>
        <hr/>
        <p>{number1}</p>
        <p>{number2}</p>
        <h2>复合数据类型展示-数组展示-单个值-下标</h2>
        <p>{arr[0]}</p>
        <p>{arr[1]}</p>
        <p>{arr[2]}</p>

        <hr/>

        <h2>复合数据类型展示-对象展示-单个值-属性</h2>
        <p>{obj['id']}</p>
        <p>{obj['username']}</p>
        <p>{obj['email']}</p>
        <hr/>

        <hr/>
        <hr/>
        <h2>复合数据类型展示-数组展示-遍历</h2>
        <p>数组如果是一维数组，jsx的插值表达式自动实现遍历操作</p>
        <div>{arr}</div>
        <hr/>

        <h2>复合数据类型展示-对象展示-遍历</h2>
        <p>如果是单个对象，我们直接使用属性的方式获取即可。如果是对象数组，则这个时候我们就需要额外的处理了。</p>

        <p>{obj['id']}</p>
        <p>{obj['username']}</p>
        <p>{obj['email']}</p>

        <hr/>
        <h2>复合数据类型展示-对象数组的展示-遍历</h2>
        <p>如果是一个对象数组，我们需要使用 map 这个 api 将数组转换为如下的写法</p>
        <p>在jsx里面，如果要给标签的属性进行赋值，则直接使用插值表达式即可，不需要使用引号包裹</p>
        {
            users.map(item => {

                return (
                    <ul key={item.id}>
                        <li>序号：{item.id}</li>
                        <li>名称：{item.username}</li>
                        <li>邮箱：{item.email}</li>
                    </ul>
                )

            })
        }

        <div className="box">直接可以在 javascript语句下面写HTML代码</div>
        <p>我是p标签</p>
        <br/>
        <label htmlFor="username">用户名：</label>
        <input type="text" id="username"/>
    </>
);


ReactDOM.render(
    <React.StrictMode>
        {jsxElement}
    </React.StrictMode>,
    document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
